﻿using SHZY.Common.Core.Manager;
using SHZY.Common.Core.Security;
using SHZY.Common.Enum;
using SHZY.Common.Extension;
using SHZY.Common.Filter;
using SHZY.Common.Security;
using SHZY.DependencyInjection;
using SHZY.DynamicApiController;
using SHZY.FriendlyException;
using SHZY.Systems.Interfaces.System;
using SHZY.system.Entitys.Dto.TestPurchaseForm;
using SHZY.system.Entitys.Dto.TestPurchaseFormOrder;
using SHZY.system.Entitys;
using SHZY.system.Interfaces;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;

namespace SHZY.system;

/// <summary>
/// 业务实现：采购订单表.
/// </summary>
[ApiDescriptionSettings(Tag = "system", Name = "TestPurchaseForm", Order = 200)]
[Route("api/system/[controller]")]
public class TestPurchaseFormService : ITestPurchaseFormService, IDynamicApiController, ITransient
{
    /// <summary>
    /// 服务基础仓储.
    /// </summary>
    private readonly ISqlSugarRepository<TestPurchaseFormEntity> _repository;

    /// <summary>
    /// 单据规则服务.
    /// </summary>
    private readonly IBillRullService _billRullService;

    /// <summary>
    /// 多租户事务.
    /// </summary>
    private readonly ITenant _db;

    /// <summary>
    /// 用户管理.
    /// </summary>
    private readonly IUserManager _userManager;

    /// <summary>
    /// 初始化一个<see cref="TestPurchaseFormService"/>类型的新实例.
    /// </summary>
    public TestPurchaseFormService(
        ISqlSugarRepository<TestPurchaseFormEntity> testPurchaseFormRepository,
        IBillRullService billRullService,
        ISqlSugarClient context,
        IUserManager userManager)
    {
        _repository = testPurchaseFormRepository;
        _billRullService = billRullService;
        _db = context.AsTenant();
        _userManager = userManager;
    }

    /// <summary>
    /// 获取采购订单表.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <returns></returns>
    [HttpGet("{id}")]
    public async Task<dynamic> GetInfo(string id)
    {
        var output = (await _repository.FirstOrDefaultAsync(x => x.Id == id)).Adapt<TestPurchaseFormInfoOutput>();

        var testPurchaseFormOrderList = await _repository.Context.Queryable<TestPurchaseFormOrderEntity>().Where(w => w.PurchaseId == output.id).ToListAsync();
        output.testPurchaseFormOrderList = testPurchaseFormOrderList.Adapt<List<TestPurchaseFormOrderInfoOutput>>();

        return output;
    }

    /// <summary>
    /// 新建采购订单表.
    /// </summary>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPost("")]
    public async Task Create([FromBody] TestPurchaseFormCrInput input)
    {
        var entity = input.Adapt<TestPurchaseFormEntity>();
        entity.Id = SnowflakeIdHelper.NextId();

        try
        {
            // 开启事务
            _db.BeginTran();

            var newEntity = await _repository.Context.Insertable<TestPurchaseFormEntity>(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteReturnEntityAsync();

            var testPurchaseFormOrderEntityList = input.testPurchaseFormOrderList.Adapt<List<TestPurchaseFormOrderEntity>>();
            if(testPurchaseFormOrderEntityList != null)
            {
                foreach (var item in testPurchaseFormOrderEntityList)
                {
                    item.Id = SnowflakeIdHelper.NextId();
                    item.PurchaseId = newEntity.Id;
                }

                await _repository.Context.Insertable<TestPurchaseFormOrderEntity>(testPurchaseFormOrderEntityList).ExecuteCommandAsync();
            }

            // 关闭事务
            _db.CommitTran();
        }
        catch (Exception)
        {
            // 回滚事务
            _db.RollbackTran();

            throw Oops.Oh(ErrorCode.COM1000);
        }
    }

    /// <summary>
    /// 更新采购订单表.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPut("{id}")]
    public async Task Update(string id, [FromBody] TestPurchaseFormUpInput input)
    {
        var entity = input.Adapt<TestPurchaseFormEntity>();
        try
        {
            // 开启事务
            _db.BeginTran();

            await _repository.Context.Updateable<TestPurchaseFormEntity>(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();

            // 清空采购订单明细表原有数据
            await _repository.Context.Deleteable<TestPurchaseFormOrderEntity>().Where(it => it.PurchaseId == entity.Id).ExecuteCommandAsync();

            // 新增采购订单明细表新数据
            var testPurchaseFormOrderEntityList = input.testPurchaseFormOrderList.Adapt<List<TestPurchaseFormOrderEntity>>();
            if(testPurchaseFormOrderEntityList != null)
            {
                foreach (var item in testPurchaseFormOrderEntityList)
                {
                    item.Id = SnowflakeIdHelper.NextId();
                    item.PurchaseId = entity.Id;
                }

                await _repository.Context.Insertable<TestPurchaseFormOrderEntity>(testPurchaseFormOrderEntityList).ExecuteCommandAsync();
            }

            // 关闭事务
            _db.CommitTran();
        }
        catch (Exception)
        {
            // 回滚事务
            _db.RollbackTran();
            throw Oops.Oh(ErrorCode.COM1001);
        }
    }

    /// <summary>
    /// 删除采购订单表.
    /// </summary>
    /// <returns></returns>
    [HttpDelete("{id}")]
    public async Task Delete(string id)
    {
        if(!await _repository.Context.Queryable<TestPurchaseFormEntity>().AnyAsync(it => it.Id == id))
        {
            throw Oops.Oh(ErrorCode.COM1005);
        }       

        try
        {
            // 开启事务
            _db.BeginTran();

            var entity = await _repository.AsQueryable().FirstAsync(it => it.Id.Equals(id));
            await _repository.Context.Deleteable<TestPurchaseFormEntity>().Where(it => it.Id.Equals(id)).ExecuteCommandAsync();

                // 清空采购订单明细表表数据
            await _repository.Context.Deleteable<TestPurchaseFormOrderEntity>().Where(it => it.PurchaseId.Equals(entity.Id)).ExecuteCommandAsync();

            // 关闭事务
            _db.CommitTran();
        }
        catch (Exception)
        {
            // 回滚事务
            _db.RollbackTran();

            throw Oops.Oh(ErrorCode.COM1002);
        }
    }
}